package com.bradz.mymovies;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpCookie;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
 



import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;
 
















import android.os.AsyncTask;
import android.util.Log;
import android.view.View;

public class ClassHttpHelper{

	private String base_url;
	private String controller;
	private List<NameValuePair> pairs;
	private String result;
	boolean check_get_after_post;
	private ClassClientHolder httpclient;
	private Object mLock = new Object();
	private ApplicationGlobalVars globals;
	private static ClassAndroidLogger logger;
	
	ClassHttpHelper(String base_url, ApplicationGlobalVars globals){
		this.base_url = base_url;
		check_get_after_post = false;
		httpclient = new ClassClientHolder();
		this.globals = globals;
		logger = new ClassAndroidLogger("ClassHttpHelper");
	}
	
	public ClassClientHolder get_client(){
		return httpclient;
	}
	
	public String get_base_url(){
		return base_url;
	}
	
	public ApplicationGlobalVars get_globals(){
		return globals;
	}
	
	public void load_client(){
		logger.info("Loading client");
		if(globals.client_loaded()){
			logger.info("Pulling client from application");
			httpclient = globals.get_client_store();
		}else{
			logger.info("Creating new client...");
			httpclient = new ClassClientHolder();
			globals.set_client_store(httpclient);
		}
	}
	
	public String postResponsefromURL(String controller, List<NameValuePair> pairs){
		
		this.controller = controller;
		this.pairs = pairs;
		this.result = "";
		
		logger.info("Received Post Request");
		
		try {
			synchronized (mLock) {
				try {
					logger.info("Locked Network Object. Sending Data to server");
					network_post_task();
				} catch (URISyntaxException e) {
					// TODO Auto-generated catch block
					logger.error("Network Post Error: " + e);
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			logger.error("Network Post Error: " + e);
			e.printStackTrace();
		}

    	return result;
    	
	}
	
	public String getResponsefromURL(String controller){

		this.controller = controller;
		this.result = "";
		
		logger.info("Received GET request");
		
		try {
			//Can't pull http data at the same time
			synchronized (mLock) {
				try {
					logger.info("Locked Network Object. Requesting data from server");
					network_get_task();
				} catch (URISyntaxException e) {
					// TODO Auto-generated catch block
					logger.error("Network Get Error: " + e);
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			logger.error("Network Get Error: " + e);
			e.printStackTrace();
		}

    	return result;
    	
    } 
	
	private URI format_url(String base, String controller) throws MalformedURLException, URISyntaxException{
		
		logger.info("URL base: " + base);
		logger.info("URL controller: " + controller);
		URL urm = new URL(base + controller);
		logger.info("Combined URL: " + urm.toString());

	    //String nullFragment = null;
	    //URI url = new URI(urm.getProtocol(), urm.getHost(), urm.getPath(), urm.getQuery(), nullFragment);
	    //url = url.normalize();
	    //String new_url = url.toString().replace("?",URLEncoder.encode("?")).replace("&",URLEncoder.encode("&"));
	    
	    //logger.info("Final Formatted URL: " + new_url);
	    
	    return urm.toURI();
	}
	
	//Make sure that the network is active and working...
	private String network_get_task() throws IOException, URISyntaxException{
	    HttpGet request;
	    HttpResponse response = null;
	    InputStream is = null;
	    
		request = new HttpGet(format_url(base_url,controller));
		
		logger.info("Sending Get Request");
		logger.info(request.getURI().getRawPath());
		
		load_client();
		
	    //httpclient.print_cookie_names();

		try{
    		response = httpclient.get_client().execute(request);
            HttpEntity entity = response.getEntity();
            StatusLine statusLine = response.getStatusLine();
    		
            logger.info("Status: " + statusLine.toString());
    		is = entity.getContent();
    		logger.info("Content: " + is.toString());
    		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    		StringBuilder sb = new StringBuilder();
    		String line = null;
    		while ((line = reader.readLine()) != null) {
    			logger.info("Line: " + line);
    			sb.append(line + "\n");
    		}
    		//This is where the post result is if it ends up mattering
    		result=sb.toString();
    		logger.info("Result: " + result);
    		//Log.d("Get URL:","URL: " + url);
    		is.close();
    	}catch(Exception e){
    		//Close the buffer if there is anything left in it
    		if(is != null && is.available()>0){
    	    	is.close();
    		}
    		logger.error("Error converting result "+e.toString());
    	}
		
		if(response != null){
			response.getEntity().consumeContent();
		}
    	/*if(response != null && response.getEntity().toString().length() > 0){
    		response.getEntity().consumeContent();
    	}*/
    	
    	return result;
	}
	
	//Make sure that the network is active and working...
	private void network_post_task() throws IOException, URISyntaxException{

	    HttpResponse response = null;
	    InputStream is = null;
	    
	    HttpPost httppost = new HttpPost(format_url(base_url,controller));
		
		load_client();
	    //httpclient.print_cookie_names();

		try {
            //httppost.setHeader("json",json.toString());
		    //response = httpclient.get_client().execute(httppost);
		    
		    httppost.setEntity(new UrlEncodedFormEntity(pairs,"UTF-8"));
		    response = httpclient.get_client().execute(httppost);
		    
			HttpEntity entity = response.getEntity();
            StatusLine statusLine = response.getStatusLine();
            
            logger.info("Status: " + statusLine.toString());
    		is = entity.getContent();
    		logger.info("Content: " + is.toString());
    		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    		StringBuilder sb = new StringBuilder();
    		String line = null;
    		while ((line = reader.readLine()) != null) {
    			logger.info("Line: " + line);
    			sb.append(line + "\n");
    		}
    		//This is where the post result is if it ends up mattering
    		result=sb.toString();
    		logger.info("Result: " + result);
        	is.close();
    	}catch(Exception e){
    		if(is != null && is.available()>0){
    	    	is.close();
    		}
    		logger.error("Error converting result "+e.toString());
    	}
    	
		if(response != null){
			response.getEntity().consumeContent();
		}
		
    	/*if(response != null && response.getEntity().toString().length() > 0){
    		response.getEntity().consumeContent();
    	}*/
    	
    	if(check_get_after_post){
			check_get_after_post = false;
			logger.info("In post post loop");
			getResponsefromURL("/user");
		}
	}
	
	private static HttpEntity createStringEntity(JSONObject params) {
	    StringEntity se = null;
	    try {
	        se = new StringEntity(params.toString(), "UTF-8");
	        se.setContentType("application/json; charset=UTF-8");
	    } catch (UnsupportedEncodingException e) {
	    	logger.error("Error creating string entity "+e.toString());
	    }
	    return se;
	}
}
